﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using UnityEngine;

public class SystemReturn
{
    private static SystemReturn self;
    private ModelLocator model;

    public SystemReturn()
    {
//        if (self == null)
//        {
//            throw new Exception("init error");
//        }
        model = ModelLocator.getInstance();
        addEvents();
    }

    public static void StartListen()
    {
        if (self == null) self = new SystemReturn();
    }

    private void addEvents()
    {
        MySocket.getInstance().addEventListener(CustomToClientFlag.SERVER_CUSTOMMSG_ADD_OBJECT, SceneAddObject);//增加对象（主角）
        MySocket.getInstance().addEventListener(SystemMsgFlag.SERVER_CUSTOM, ServerCustom);//自定义消息消息头20

        MySocket.getInstance().addEventListener((int)SystemMsgFlag.MessageTypeSC.NSM_SYNC_PSH, SyncMessage);//同步消息

        //表格相关增/删/改/
        MySocket.getInstance().addEventListener(SystemMsgFlag.SERVER_RECORD_ADDROW, ServerRecordAddRow);
        MySocket.getInstance().addEventListener(SystemMsgFlag.SERVER_RECORD_DELROW, ServerRecordDelRow);
        MySocket.getInstance().addEventListener(SystemMsgFlag.SERVER_RECORD_GRID, ServerRecordGrid);
		
		ModelLocator.getInstance().addEventListener(CustomToClientFlag.SERVER_CUSTOMMSG_ADD_MAINROLE, SceneAddMainRole);//增加对象（主角）
	}
	
	private void SceneAddMainRole(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx btArr = (ByteArrayEx)e.data[0];
		
		btArr.readByte();
        Point objID = btArr.readObject();
        PlayerData.Instance().SceneId = btArr.readInt();
		string playerName = btArr.readMultiByteEx();
		byte profession = btArr.readByte();
		byte sex = btArr.readByte();
		
		string modelPath = "";
		if(sex == (byte)GameDefine.Sex.FEMALE){
			modelPath = SqliteReader.getInstance().getIniVal("RoleInfo","RoleID",profession.ToString(),new string[]{"Woman"})[0];
		} else {
			modelPath = SqliteReader.getInstance().getIniVal("RoleInfo","RoleID",profession.ToString(),new string[]{"Man"})[0];
		}
		
		string headPic = btArr.readMultiByteEx();
        model.scene.Role.ObjID = objID;

        model.scene.AddMainRole(objID,playerName,modelPath,headPic,(int)profession);
		
    }
	
    /// <summary>
    /// 增加主角对象
    /// </summary>
    private void SceneAddObject(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx btArr = new ByteArrayEx((byte[])e.data[0]);
        Point objID = btArr.readObject();
        int objType = btArr.readInt();
        int objModelID = btArr.readInt();
        int count = btArr.readInt();
        model.scene.Role.ObjID = objID;

        model.scene.AddObj(objID, objType, objModelID, count, btArr);

    }
    /// <summary>
    /// 同步消息
    /// </summary>
    private void SyncMessage(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx msg = new ByteArrayEx((byte[])e.data[0]);

        int syncType = (int)msg.readByte();//同步消息类型(0:场景;1:对象)//

        if (syncType == 1)
        {
            int objMessageType = (int)msg.readByte();//对象消息类型：0 新增 1 删除 2 改变 //

            if (objMessageType == 0)
            {
                //基本信息//
                Point ObjID = msg.readObject();//对象ID//
                int objType = (int)ObjID.QueryType();
                int sceneID = (int)msg.readInt();//所在场景ID//
                UInt64 parentID = (UInt64)msg.readUInt64();//父对象ID//
                int PosX = (int)msg.readInt();//位置x//
                int PosY = (int)msg.readInt();//位置y//
                int tag = (int)msg.readInt();//Tag//

                switch (objType)
                {
                    case ObjType.Npc:
                    case ObjType.Monster:
                        int MonsterObjState = (int)msg.readByte();//对象状态//
                        int MonsterMoveState = (int)msg.readByte();//移动状态//
                        break;
                    case ObjType.Player:
						int PlayerObjState = (int)msg.readByte();//对象状态//
                        int PlayerMoveState = (int)msg.readByte();//移动状态//
                        int PlayerIsVisible = (int)msg.readInt();//玩家可见性//
                        break;
                }

                SceneObject sceneAddObj = new SceneObject(ObjID,0,0);
                model.scene.HandlePropertiesEx(ObjID.ToString(), sceneAddObj);
				sceneAddObj.HandlePropertiesEx("PosX", PosX);
				sceneAddObj.HandlePropertiesEx("PosY", PosY);

                while (msg.bytesAvailable > 0)
                {
                    int addType = (int)msg.readByte();//字段类型：0 属性字段1 表字段//
                    if (addType == 0)
                    {
                        int addFieldNum = (int)msg.readUnsignedShort();//字段数量[uint16]//
                        for (int h = 0; h < addFieldNum; h++)
                        {
                            string addFieldName = msg.readMultiByteEx();//字段名//
                            int subAddFieldType = (int)msg.readByte();//字段类型//
                            System.Object addKeyValue = msg.GetDataByType(subAddFieldType);
                            sceneAddObj.HandlePropertiesEx(addFieldName, addKeyValue);
                        }
                    }
                    else if (addType == 1)
                    {
                        int addRecordNum = (int)msg.readUnsignedShort();//表数量//
                        for (int l = 0; l < addRecordNum; l++)
                        {
                            string recordName = msg.readMultiByteEx();//表名//
                            Record objRecord;
                            if (!sceneAddObj.CheckProperties(recordName))
                            {
                                objRecord = new Record(recordName);
                            }
                            else
                            {
                                objRecord = sceneAddObj.GetProperties(recordName) as Record;
                            }
                            

                            int rowNums = (int)msg.readInt();//行数//
                            int colNums = (int)msg.readUnsignedShort();//列数//

                            for (int mm = 0; mm < colNums; mm++)
                            {
                                string fieldName = msg.readMultiByteEx();//字段名//
                                int fieldType = msg.readByte();//字段类型//
                            }

                            for (int z = 0; z < rowNums; z++)
                            {
                                int rowNum = (int)msg.readInt()-1;//行号//
                                objRecord.AddRecordRow(rowNum, colNums, msg);
                            }
                            sceneAddObj.HandlePropertiesEx(recordName, objRecord);
                        }
                    }
                }
                
            }
            else if (objMessageType == 2)
            {
				//基本信息//
                Point ObjID = msg.readObject();//对象ID//
				int objType = (int)ObjID.QueryType();
                int sceneID = (int)msg.readInt();//所在场景ID//
                UInt64 parentID = (UInt64)msg.readUInt64();//父对象ID//
                int PosX = (int)msg.readInt();//位置x//
                int PosY = (int)msg.readInt();//位置y//
                int tag = (int)msg.readInt();//Tag//

                switch (objType)
                {
                    case ObjType.Npc:
                    case ObjType.Monster:
                        int MonsterObjState = (int)msg.readByte();//对象状态//
                        int MonsterMoveState = (int)msg.readByte();//移动状态//
                        break;
                    case ObjType.Player:
						int PlayerObjState = (int)msg.readByte();//对象状态//
                        int PlayerMoveState = (int)msg.readByte();//移动状态//
                        int PlayerIsVisible = (int)msg.readInt();//玩家可见性//
                        break;
                }
				
                SceneObject sceneObj = (SceneObject)model.scene.GetProperties(ObjID.ToString());
				sceneObj.HandlePropertiesEx("PosX", PosX);
				sceneObj.HandlePropertiesEx("PosY", PosY);

                while (msg.bytesAvailable > 0)
                {

                    int operateType = (int)msg.readByte();//操作类型:0 新增字段 1 删除字段 2 改变字段//

                    if (operateType == 0)
                    {
                        int addType = (int)msg.readByte();//字段类型：0 属性字段1 表字段//
                        if(addType == 0)
                        {
                            int addFieldNum = (int)msg.readUnsignedShort();//字段数量[uint16]//
                            for (int h = 0; h < addFieldNum; h++)
                            {
                                string addFieldName = msg.readMultiByteEx();//字段名//
                                int subAddFieldType = (int)msg.readByte();//字段类型//
                                System.Object addKeyValue = msg.GetDataByType(subAddFieldType);
                                sceneObj.HandlePropertiesEx(addFieldName, addKeyValue);
                            }
                        }
                        else if (addType == 1)
                        {
                            int addRecordNum = (int)msg.readUnsignedShort();//表数量//
                            for (int l = 0; l < addRecordNum; l++)
                            {
                                string recordName = msg.readMultiByteEx();//表名//

                                Record objRecord;

                                if (!sceneObj.CheckProperties(recordName))
                                {
                                    objRecord = new Record(recordName);
                                }
                                else
                                {
                                    objRecord = sceneObj.GetProperties(recordName) as Record;
                                }

                                int rowNums = (int)msg.readInt();//行数//
                                int colNums = (int)msg.readUnsignedShort();//列数//

                                for (int mm = 0; mm < colNums; mm++)
                                {
                                    string fieldName = msg.readMultiByteEx();//字段名//
                                    int fieldType = msg.readByte();//字段类型//
                                }

                                for (int z = 0; z < rowNums; z++)
                                {
                                    int rowNum = (int)msg.readInt()-1;//行号//
                                    objRecord.AddRecordRow(rowNum, colNums, msg);
                                }
                                sceneObj.HandlePropertiesEx(recordName, objRecord);
                            }
                        }
                    }
                    else if (operateType == 2)
                    {
                        int fieldType = (int)msg.readByte();//字段类型：0 属性字段 1 表字段//
                        if (fieldType == 0)
                        {
                            int fieldNum = (int)msg.readUnsignedShort();//字段数量[uint16]//
                            for (int j = 0; j < fieldNum; j++)
                            {
                                string fieldName = msg.readMultiByteEx();//字段名//
                                int subFieldType = (int)msg.readByte();//字段类型//
                                System.Object keyValue = msg.GetDataByType(subFieldType);
                                sceneObj.HandlePropertiesEx(fieldName, keyValue);
                            }
                        }
                        else if (fieldType == 1)
                        {
                            int recordNum = (int)msg.readUnsignedShort();//表数量//
                            for (int k = 0; k < recordNum;k++ )
                            {
                                string recordName = msg.readMultiByteEx();//表名//
                                Record objRecord = (Record)sceneObj.GetProperties(recordName);

                                int rowNums = (int)msg.readInt();//行数//
                                int colNums = (int)msg.readUnsignedShort();//列数//
                                for (int m = 0; m < rowNums;m++ )
                                {
                                    int rowNum = (int)msg.readInt()-1;//行号//
                                    int actType = (int)msg.readByte();//行为[0:增，1:删，2:改]//
                                    if(actType == 0)
                                    {
                                        objRecord.AddRecordRow(rowNum, colNums, msg);
                                    }
                                    else if (actType == 2)
                                    {
                                        objRecord.ChangeRecord(rowNum,colNums,msg);
                                    }
                                    else if (actType == 1)
                                    {
                                        objRecord.DelRow(rowNum);
                                    }
                                }
                            }
                        }


                    }
                    else if (operateType == 1)
                    {
                        int num = msg.readUnsignedShort();//数量[uint16]//
                        for (int i = 0; i < num; i++)
                        {
                            string keyName = msg.readMultiByteEx();//字段名//
                            int type = msg.readByte();//字段类型: 0为字段  1为表数据//
                            sceneObj.DeletePropertiesEx(keyName);
                        }
                    }

                }

            }
            else if (objMessageType == 1)
            {
                Point objID = msg.readObject();//对象ID//
                model.scene.DelObjByCustom(objID);
            }
        }
        else if (syncType == 0)
        {

        }





    }

    /// <summary>
    /// 自定义消息，增/删/改/场景对象
    /// </summary>
    private void ServerCustom(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx msg = new ByteArrayEx((byte[])e.data[0]);
        if (msg.length <= 20)
        {
            //消息不完整，自定义消息没有任何数据，因为自定义消息的最短长度应该大于20//
            Console.WriteLine("错误", "自定义消息没有数据");
            return;
        }

        //Point ObjectId		= msg.readObject();
        //Point AsyncId		= msg.readObject();
        int nArgNum = msg.readInt();    //参数数量

        int type = msg.readByte();


        int command = (int)msg.GetDataByType(type);

        object[] ArgValue = new object[nArgNum];

        for (int i = 0; i < nArgNum - 1; i++)
        {
            type = msg.readByte();
            ArgValue[i] = msg.GetDataByType(type);
        }

        switch (command)
        {
            case CustomToClientFlag.SERVER_CUSTOMMSG_ADD_OBJECT://添加对象//
                model.scene.AddObjByCustom(ArgValue);
                break;
            case CustomToClientFlag.SERVER_CUSTOMMSG_OBJECT_PROPERTY_CHANGE://显示对象属性修改//
                model.scene.UpdataObjByCustom(ArgValue);
                break;
            case CustomToClientFlag.SERVER_CUSTOMMSG_OBJECT_DEL://删除显示对象//
                //model.scene.DelObjByCustom(ArgValue);
                break;
            default:
                break;
        }
        model.dispacthEvent(command, ArgValue);
    }

    /// <summary>
    /// 表格增加行
    /// string	表名
    /// int 插入行号
    /// int 插入行数
    /// </summary>
    private void ServerRecordAddRow(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx msg = new ByteArrayEx((byte[])e.data[0]);

        string recName = msg.readMultiByteEx();
        int nRow = msg.readInt();
        int nRows = msg.readInt();

        Debug.Log("↓收到引擎消息(表格添加行)+" + "recordName" + recName + ",nRow:" + nRow + ",nRows:" + nRows);

        if (!model.scene.CheckProperties(recName))
        {
            //表格不存在
            Debug.Log("不存在名为[" + recName + "]表格！表格数据添加失败。");
            return;
        }
        Record record = model.scene.GetProperties(recName) as Record;

        record.AddRow(nRow, nRows, msg);
    }
    /// <summary>
    /// 删除表格行
    /// string 表名
    /// int 删除行号
    /// </summary>
    private void ServerRecordDelRow(System.Object obj, DispatchEventArgs e)
    {
        //			_UI16	nIndex;		// 表序号
        //			_UI16	nRow;		// 删除的行号

        ByteArrayEx msg = new ByteArrayEx((byte[])e.data[0]);
        string recName = msg.readMultiByteEx();
        int nRow = msg.readInt();


        Debug.Log("↓收到引擎消息(表格删除行),recName:" + recName + ",nRow:" + nRow);

        if (!model.scene.CheckProperties(recName))
        {
            //表格不存在
            Debug.Log("不存在名为[" + recName + "]表格！表格数据删除失败。");
            return;
        }
        Record record = model.scene.GetProperties(recName) as Record;
        record.DelRow(nRow);
    }
    /// <summary>
    /// 表数据修改
    /// string 表名
    /// int 要修改的数据数量
    /// msg 包含，行，列，及数据
    /// </summary>
    private void ServerRecordGrid(System.Object obj, DispatchEventArgs e)
    {
        ByteArrayEx msg = new ByteArrayEx((byte[])e.data[0]);
        string recName = msg.readMultiByteEx();
        int nCount = msg.readInt();


        Debug.Log("↓收到引擎消息(表格修改行),recName:" + recName + ",nCount:" + nCount);

        if (!model.scene.CheckProperties(recName))
        {
            //表格不存在
            Debug.Log("不存在名为[" + recName + "]表格！表格数据修改失败。");
            return;
        }
        Record record = model.scene.GetProperties(recName) as Record;
        record.ChangeRecordGrid(nCount, msg);
    }


}